package com.xinsoft.common.exception;

import com.xinsoft.common.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 异常处理器
 */
@RestControllerAdvice
public class BDExceptionHandler {
    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 自定义业务异常 异常处理
     * @Description 不需要打印错误日志，直接返回前端
     * @param e:
     * @Author Li9527
     * @Date 2023-5-23 10:53:42
     * @return Response
     */
    @ExceptionHandler(BDException.class)
    public Response<?> handleMyException(BDException e) {
        Response r = new Response();
        r.setCode(e.getCode() + "");
        r.setMessage(e.getMessage());
        logger.error(e.getMessage(), e);
        return r;
    }

    /**
     * 接口路径不存在 异常处理
     * @Description 暂时先打印错误日志
     * @param e:
     * @Author Li9527
     * @Date 2023-5-23 10:53:45
     * @return Response
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    public Response<?> handlerNoFoundException(Exception e) {
        logger.error("路径不存在，请检查路径是否正确", e);
        return Response.fail("404", "路径不存在，请检查路径是否正确");
    }


//    @ExceptionHandler({Exception.class})
//    public Object handleException(Exception e, HttpServletRequest request) {
//        logger.error("系统异常", e);
//        return Response.fail(e.getMessage());
//    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Response<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
        String msg = e.getBindingResult().getFieldErrors().stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.joining(","));
        logger.error(String.format("参数校验失败：%s", msg), e);
        return Response.fail(msg);
    }

    @ExceptionHandler(ConstraintViolationException.class)
    public Response<?> handleConstraintViolationException(ConstraintViolationException e){
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        String msg = violations.stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining(","));
        logger.error(String.format("参数校验失败：%s", msg), e);
        return Response.fail(msg);
    }

    @ExceptionHandler(NullPointerException.class)
    public Response<?> handleNullPointerException(NullPointerException e){
        logger.error("该方法存在空指针异常，请修复代码", e);
        Response r = new Response();
        r.setCode("4000");
        r.setMessage("该方法存在空指针异常，请修复代码");
        return r;
    }
}
